<?php
/**
 * request.class.php
 * 
 * Request params wrapper
 * 
 * @version:	0.4
 * @package:	core
 * @author:	alex_ez
 * @created:	15 nov 2008
 *
 * @link:	http://src.qfox.ru/
 *
 * @copyright:	(c) 2008 flamebox.ru. All rights reserved.
 */

if( defined( '__REQUEST.CLASS_PHP' ) ) return;
define( '__REQUEST.CLASS_PHP', '0.4' );

// by axelys (for windows support):

if(!function_exists('fnmatch')) {

    function fnmatch($pattern, $string) {
        return preg_match("#^".strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' => '.'))."$#i", $string);
    } // end

} // end if

class request extends singleton
{
	// php singleton wrapper
	static public function &__getMe( ) { return parent::__getMe( __CLASS__ ); }
	static public function &instance() { return parent::__getMe(__CLASS__); }
	
	private $raw_url = null;
	private $raw_get = null;
	
	private $params = null;
	
	protected final function __construct( )
	{
		$uri = @parse_url( $this ->getUri( ) );
		if( $uri == false ) response::__getMe( ) ->badrequest( );
		
		$this ->raw_url = $uri['path'];
		$this ->raw_get = isset( $uri['query'] ) ? $uri['query'] : null;
		
		if( strpos( $this ->raw_url, '//' ) !== false )
		{
			// rewrite url
			$r = response::__getMe( );
			
			$url = $this ->raw_url;
			while( strpos( $url, '//' ) !== false ) $url = str_replace( '//', '/', $url );
			if( !is_null( $this ->raw_get ) ) $url .= '?'.$this ->raw_get;
			$r ->seeother( $url );
		}
		
		//var_dump( $uri );
		//$this->raw_url = ($url !== null)? $url: $_SERVER['REQUEST_URI'];
		//$this->raw_url = '/news/';
		
		//while(  )
		$rup = explode( '/', $this ->raw_url );
		
		//$this ->path = explode( '/', $this ->raw_url );
		//$this ->params['class'] = sizeof( $rup ) ? array_shift( $rup );
		//$this ->params['method'] = sizeof( $rup ) ? array_shift( $rup ) : "index";
		foreach( $rup as $p )
		if( $p != '' )
			$this ->params[] = $p;
	}
	
	public function __get( $k )
	{
		if( $k == 'params' || $k == 'path' ) return $this ->params;
		if( $k == 'data' )
		{
			$r = array( );
			foreach( array( 'get','post','files' ) as $a )
				$r[$a] = $this ->$a( $this ->__get( 'keys_'.$a ) );
			return $r;
		}
		
		if( ($i = strpos( $k, '_' )) === false ) return null;
		$p = substr( $k, $i+1 );
		switch( substr( $k, 0, $i ) )
		{
		case 'raw':
			if( $p == 'url' ) return $this ->raw_url;
			if( $p == 'get' ) return $this ->raw_get;
			break;
		case 'g':
		case 'get':
			return $this ->g( $p );
		case 'p':
		case 'post':
			return $this ->p( $p );
		case 'c':
		case 'cookie':
			return $this ->c( $p );
                case 'r':
                case 'req':
                    return $this ->r( $p );
		case 'f':
		case 'file':
		case 'files':
			return $this ->f( $p );
		case 'keys':
			if( !strpos( ',get,post,cookie,files', $p ) ) return null;
			$rf = create_function( '', sprintf( 'return isset( $_%1$s ) && is_array( $_%1$s ) ? array_keys( $_%1$s ) : null;', strtoupper( $p ) ) );
			return $rf();
		default:
			return isset( $_GET[$p] ) ? $_GET[$p]
				: ( isset( $_POST[$p] ) ? $_POST[$p]
				: ( isset( $_COOKIE[$p] ) ? $_COOKIE[$p] : null ) );
		}
	}
	
	public function __isset( $k )
	{
		return !is_null( $this ->__get( $k ) );
	}
	
	public function __unset( $k )
	{
		if( $k[0] !== 'c' || $k[1] !== '_' ) return;
		$k = substr( $k, 2 );
		setcookie( $k, '', time()-3600 );
	}

	public function req( $k = null ) { return $this ->r( $k ); }
	public function r( $k = null )
	{
		if( is_null( $k ) ) return null;
		if( is_array( $k ) ) { $r = array( ); foreach( $k as $_k ) $r[$_k] = $this ->r( $_k ); return $r; }
		return isset( $_REQUEST[$k] ) ? ( $_REQUEST[$k]=='' ? true : $_REQUEST[$k] ) : null;
	}
	
	public function get( $k = null ) { return $this ->g( $k ); }
	public function g( $k = null )
	{
		if( is_null( $k ) ) return null;
		if( is_array( $k ) ) { $r = array( ); foreach( $k as $_k ) $r[$_k] = $this ->g( $_k ); return $r; }
		return isset( $_GET[$k] ) ? ( $_GET[$k]=='' ? true : $_GET[$k] ) : null;
	}
	
	public function post( $k = null ) { return $this ->p( $k ); }
	public function p( $k = null )
	{
		if( is_null( $k ) ) return null;
		if( is_array( $k ) ) { $r = array( ); foreach( $k as $_k ) $r[$_k] = $this ->p( $_k ); return $r; }
		return isset( $_POST[$k] ) ? $_POST[$k] : null;
	}
	
	public function cookie( $k = null ) { return $this ->c( $k ); }
	public function c( $k = null )
	{
		if( is_null( $k ) ) return null;
		if( is_array( $k ) ) { $r = array( ); foreach( $k as $_k ) $r[$_k] = $this ->c( $_k ); return $r; }
		return isset( $_COOKIE[$k] ) ? $_COOKIE[$k] : null;
	}

	public function files( $k = null ) { return $this ->f( $k ); }
	public function file( $k = null ) { return $this ->f( $k ); }
	public function f( $k = null )
	{
		if( is_null( $k ) ) return null;
		if( is_array( $k ) ) { $r = array( ); foreach( $k as $_k ) $r[$_k] = $this ->f( $_k ); return $r; }
		return isset( $_FILES[$k] ) ? $_FILES[$k] : null;
	}
	
	
	public function getReferer( )
	{
		if( !isset( $_SERVER['HTTP_REFERER'] ) ) return '/';
		$r = $_SERVER['HTTP_REFERER'];
		
		$__url = sprintf( '%s://%s/', $this ->getProtocol( ), $this ->getHost( ) );
		if( strpos( strtolower( $r ), $__url ) === 0 )
			$r = substr( $r, strlen( $__url )-1 );
		
		return $r;
	}
	
	public function getHost( )
	{
		return strtolower( $_SERVER['HTTP_HOST'] );
	}
	
	public function getUri( )
	{
		return isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '';
	}
	
	public function getUrl( )
	{
		return $this ->getUri( );
	}

	public function getUrlPath( )
	{
		return $this ->raw_url;
	}

	public function getProtocol( )
	{
		@list( $proto, ) = explode( '/', $_SERVER['SERVER_PROTOCOL'] );
		return strtolower( $proto );
	}

	public function getProtocolVersion( )
	{
		@list( , $version ) = explode( '/', $_SERVER['SERVER_PROTOCOL'] );
		return (float)$version;
	}
	
	public function getIp( )
	{
		return isset( $_SERVER[ 'REMOTE_ADDR' ] ) ? $_SERVER[ 'REMOTE_ADDR' ] : '127.0.0.1';
	}
	
	public function getPort( )
	{
		return isset( $_SERVER[ 'SERVER_PORT' ] ) ? $_SERVER[ 'SERVER_PORT' ] : '80';
	}
	
	public function getMethod( )
	{
		return strtolower( $_SERVER[ 'REQUEST_METHOD' ] );
	}
	
	public function getScheme( )
	{
		$scheme = 'http';
		if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') $scheme .= 's';
		return $scheme;
	}

	public function getRoot( )
	{
		return sprintf( "%s://%s:%d/", $this ->getScheme(), $this ->getHost( ), $this ->getPort( ) );
	}
	
	public function getUserAgent( )
	{
		return isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? $_SERVER[ 'HTTP_USER_AGENT' ] : 'tty';
	}
	
	
	
	public function isPostMethod( )
	{
		return ($this ->getMethod( ) == 'post');
	}
	public function isGetMethod( )
	{
		return ($this ->getMethod( ) == 'get');
	}
	
	public function isAJAX( )
	{
		return ( $this ->path[0] == 'ajax' && isset( $this ->path[1] ) && isset( $this ->path[2] ) );
	}
	
	public function isFlash( )
	{
		//echo strpos( $this ->getUserAgent(), 'flash' );
		return false !== stripos( $this ->getUserAgent(), 'flash' ); //( $this ->path[0] == 'ajax' && isset( $this ->path[1] ) && isset( $this ->path[2] ) );
	}
	
	public function isXml( )
	{
		return array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER);
	}
	
	public function isValid( )
	{
		if (preg_match('/^([a-zA-Z0-9\-\_\/]*)(\?(.*))?$/', $this->raw_url) && false === strpos($this->raw_url, 'undefined')) 
		{
			return true;
		}
		else return false;
	}
	
	
	public function isAccepted( $type, $q = 0 )
	{
		if( !$type ) return false;
		
		$accepts = $this ->parseWeighted( $_SERVER['HTTP_ACCEPT'] );
		foreach( $accepts as $k => $p )
			if( fnmatch( $k, $type ) && $p['q'] > $q ) return true;
		
		return false;
	}
	
	
//		// geoip
//		case 'country': return $_SERVER['GEOIP_COUNTRY_NAME']; break;
//		case 'countryCode': return $_SERVER['GEOIP_COUNTRY_CODE']; break;
	
	public function isLocal( )
	{
		//var_dump( $_SERVER['REMOTE_ADDR'] );
		return false;
	}
	
	// user agent and addresses
	public function isBot( )
	{
		$user_agent = strtolower( isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '' );
		return preg_match('/(yandex|rambler|google|webalta|aport|msnbot|scooter|yahoo|appie|architext|ask|bot|crawl|fast|fetch|find|ia_archiver|index|java|libwww|nutch|price|robo|scan|search|seek|slurp|sohu|spider|spyder|teoma|walk|wget|winhttp|mail)/', $user_agent);
	}
	
	public function is_developer( ) { return $this ->isDeveloper( ); }
	public function isDeveloper( )
	{
		$addrs = config::__getMe( ) ->developers__addrs;
		return ( strpos( $addrs, $this ->getIP() ) !== false );
	}
	
	
	// utilites
	private function parseWeighted( $s )
	{
		// text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 -> array
		$s = explode( ',', $s );
		$r = array( );
		foreach( $s as $p )
		{
			$p = explode( ';', $p );
			if( !isset( $p[1] ) ) $p[1] = "q=1.0";
			parse_str( $p[1], $r[$p[0]] );
			$r[$p[0]]['q'] = (float)($r[$p[0]]['q']);
		}
		return $r;
	}
}

?>